#include "ammeterscale.h"
#include "Device/ReadUsbPort/readusbport.h"
#include "Setting/BasicSetting/basicsettingwidget.h"

#define NEW_AMMETER //switch old and new AMMETER



AmmeterScale::AmmeterScale(QString port,QString baud,QString dataBits,QString parity,QString stopBits,QObject *parent) :
    QObject(parent),
    m_timerAutoSend(new QTimer(this)),
    m_threadForSerial(new QThread(this)),
    m_RxQuene(RX_VOL_CMD),
    m_TxQuene(TXRX_NULL)
{
    m_timerAutoSend->setSingleShot(true);
    initModbusSetting( port, baud, dataBits, parity, stopBits);

    if(BasicSettingWidget::getOprtMode() == BasicSettingWidget::PUNCHING_MODE)
    {
        writeCmd("06","0F","00","10","RTU","02","01 00",false);
    }
    else
    {
        writeCmd("02","0F","00","10","RTU","02","01 00",false);
    }

    qDebug() << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<Q_FUNC_INFO << port << baud << dataBits << parity << stopBits;
}

AmmeterScale::~AmmeterScale()
{
    m_threadForSerial->exit();
    m_threadForSerial->terminate();
    if(m_port)
    {
        delete m_port;
    }
}

quint8 AmmeterScale::LSBUS_sum (QByteArray buf)
{
    quint8 sum = 0x00;
    for ( int i = 1 ; i < buf.count() ; i ++ )
    {
        sum += buf.at(i);
    }
    return sum;
}

QByteArray AmmeterScale::toHexString(QByteArray buf)
{
    QByteArray temp = "";
    for(int i =0; i < buf.count() ; i ++ )
    {
        if( i == buf.count() -1 )
            temp += buf.mid(i, 1).toHex();
        else
            temp += buf.mid(i, 1).toHex() + " ";
    }
    return temp;
}

void AmmeterScale::initModbusSetting(QString port,QString baud,QString dataBits,QString parity,QString stopBits)
{
    mComPortSetting.cmbComPort = port;
    mComPortSetting.cmbBaudrate = baud;
    mComPortSetting.cmbDataBits = dataBits;
    mComPortSetting.cmbParity  = parity;
    mComPortSetting.cmbStopBits = stopBits;
    createConnection();
}

void AmmeterScale::createConnection()
{
    qDebug () << Q_FUNC_INFO;
    m_port = new SerialPort();
    // for serial
    connect(m_port,                     SIGNAL(sgReceivedData(QByteArray)),     this,               SLOT(onRecvedData(QByteArray) ));
    connect(m_port,                     SIGNAL(sgReceivedErrorData(QByteArray)),this,               SLOT(onRecvedErrorData(QByteArray) ));
    connect(m_port,                     SIGNAL(sgSendedData(QByteArray)),       this,               SLOT(onSendedData(QByteArray)   ));
    connect(m_threadForSerial,          SIGNAL(finished()),                     m_port,             SLOT(deleteLater())                 );
    connect(m_threadForSerial,          SIGNAL(started()),                      m_port,             SLOT(init())                 );
    connect(m_port,                     SIGNAL(sgConnected()),                  this,               SLOT(onPortConnected()                        ));
    connect(m_port,                     SIGNAL(sgDisconnected()),               this,               SLOT(onPortDisconnected()                     ));

    //时机很重要，所以要提高优先顺序
    m_port->moveToThread(m_threadForSerial);
    m_threadForSerial->start(QThread::TimeCriticalPriority);
    m_port->setResponseTimeout(2000);//设置Port超时时间
    connect(this,                       SIGNAL(toggleAutoSend(bool)),              this, SLOT(onChkAutoSendToggled(bool)               ));
    connect(this,                       SIGNAL(sendRequestList(QStringList)),         this, SLOT(onReceiveWriteList(QStringList) ));
    connect(m_timerAutoSend,            SIGNAL(timeout()),                          this, SLOT(onTimerAutoSendTimeout()                 ));


    toggleAutoSend(true);

}

int AmmeterScale::onParseData(QStringList &parsedData, QByteArray data)
{
    QString timeStamp = QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
    QString status = "";
    QString rawData = QString(AmmeterScale::toHexString(data));
    QString slaveAddr = "";
    QString function = "";
    QString info = "";
    QString crc = "";
    QString commMode = "RTU";

    int exception_code = 0x00;
    if ( commMode == "RTU") {
        if ( data.count() >= 4 ) {
            slaveAddr = QString( data.mid(0, 1).toHex() );
            function = QString( data.mid(1, 1).toHex() );
            crc = QString( data.mid(data.count() -2 , 2).toHex() );

            if ( data.at(1) & 0x80 ) {
                exception_code = data.at(2);
            }
            quint16 crc_result = 0x0ffff;
            if ( check_ModbusRTU_CRC16(data, crc_result) == true ) {
                if ( exception_code != 0x00 ) {
                    info += QString("[ERROR CODE] ") + data.mid(2, data.count() - 4).toHex();
                    exception_code = 0xff;
                }
            }
            else {
                info = QString("[ERROR CRC] expected %1").arg(crc_result, 4, 16, QChar('0'));
                exception_code = 0xff;
            }
        }
        else {
            exception_code = 0xff;
        }
    }
    else if ( commMode == "LSBUS") {
        if ( data.count() >= 4 ) {
            QString response_start = QString( data.mid(0, 1).toHex() );
            slaveAddr = QString( data.mid(1, 2) );
            function = QString( data.mid(3, 1) );
            crc = QString( data.mid(data.count() -3, 2) );
            quint8 sum = LSBUS_sum(data.mid(0, data.count() - 3));
            if ( sum == crc.toInt(NULL, 16) ) {
                if ( response_start == "15" ) {
                    info += QString("[ERROR CODE] ") + data.mid(4, 2) + "  ";
                    exception_code = 0xff;
                }
                info += "" + data.mid(0, data.count()) ;
            }
            else {
                info = QString("[ERROR SUM] expected %1").arg(sum, 4, 16, QChar('0'));
                exception_code = 0xff;
            }
        }
        else {
            exception_code = 0xff;
        }
    }
    if ( exception_code != 0x00 ) {
        status = "NOK]";
    }
    else {
        status = "OK]";
    }
    parsedData << timeStamp << status << commMode << rawData << crc << slaveAddr << function << info;
    return exception_code;
}

void AmmeterScale::onChkAutoSendToggled(bool checked)
{
    int interval = 1500;//auto send interval is 1500ms
    if ( checked == true ) {
        connect(m_port, SIGNAL(sgReadyEntered()), m_timerAutoSend, SLOT(start()));

        //writeCmd("02","0F","00","10","RTU","02","01 00",false);

        m_timerAutoSend->setInterval( interval );
        m_timerAutoSend->start();
    }
    else {
        disconnect(m_port, SIGNAL(sgReadyEntered()), 0, 0);
        m_timerAutoSend->stop();
    }
}

void AmmeterScale::readAmmeterInfo(QString mSlaveAddr, QString mFunctionCode, QString mStartAddr, QString mNumOfRegister, QString mCommMode, QString mbyteCount)
{
    QByteArray slaveAddr = mSlaveAddr.simplified().mid(0, 2).toLatin1();
    QByteArray functionCode =mFunctionCode.simplified().mid(0, 2).toLatin1();
    QByteArray startAddr = mStartAddr.simplified().mid(0, 4).toLatin1();
    QByteArray writeData = "";//ui->lineWriteData->text().simplified().toLatin1();
    QByteArray numOfRegister =QByteArray("0000" + mNumOfRegister.toLatin1()).right(4);
    QByteArray byteCount = "";
    QString commMode = mCommMode;
    byteCount.setNum(mbyteCount.toInt(0, 16) * 2, 16);
    byteCount = "00" + byteCount;
    byteCount = byteCount.right(2);
    QByteArray sendData = "";
    if ( commMode.contains("RTU")) {
        int tempStartAddr =    startAddr.toInt(NULL, 16);
        startAddr = QByteArray("0000" + QByteArray::number(tempStartAddr, 16)).right(4);
        sendData = makeRTUFrame(slaveAddr, functionCode, startAddr, numOfRegister, byteCount, writeData);
    }
    else {
        sendData = makeLSBUSFrame(slaveAddr, functionCode, startAddr, numOfRegister, byteCount, writeData);
    }
    QStringList parsedData;
    onParseData(parsedData, sendData);//含CRC校验
    emit sendRequestList(parsedData);
}

void AmmeterScale::writeCmd(QString slaveAddr, QString functionCode,QString startAddr,QString numOfRegister,QString commMode,QString byteCount,QString inputDataString,bool intputFlag)
{
    QByteArray mSlaveAddr = slaveAddr.simplified().mid(0, 2).toLatin1();
    QByteArray mFunctionCode = functionCode.simplified().mid(0, 2).toLatin1();
    QByteArray mStartAddr = startAddr.simplified().mid(0, 4).toLatin1();
    QString writeDreadAmmeterInfoata;
    QByteArray mWriteData;
    /*if(intputFlag){
        writeData = QString("%1").arg(inputDataString.toInt(), 4, 16, QLatin1Char('0'));//convert to hexString
        mWriteData = writeData.simplified().toLatin1();
    }*/
    if(intputFlag == false){
        mWriteData = inputDataString.simplified().toLatin1();
    }
    QByteArray mNumOfRegister = QByteArray("0000" + numOfRegister.toLatin1()).right(4);
    QByteArray mByteCount = byteCount.simplified().mid(0, 2).toLatin1();

    //mByteCount.setNum(byteCount.toInt(0, 16) , 16);
    //mByteCount = "00" + mByteCount;
    //mByteCount = mByteCount.right(2);
    QByteArray sendData = "";
    if( commMode.contains("RTU"))
    {
        int tempStartAddr =    mStartAddr.toInt(NULL, 16);
        mStartAddr = QByteArray("0000" + QByteArray::number(tempStartAddr, 16)).right(4);
        sendData = makeRTUFrame(mSlaveAddr, mFunctionCode, mStartAddr, mNumOfRegister, mByteCount, mWriteData);
    }
    else
        sendData = makeLSBUSFrame(mSlaveAddr, mFunctionCode, mStartAddr, mNumOfRegister, mByteCount, mWriteData);
    QStringList parsedData;
    onParseData(parsedData, sendData);//含CRC校验
    qDebug() <<"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"<< Q_FUNC_INFO << sendData;
    emit sendRequestList(parsedData);
    qDebug() <<"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"<< Q_FUNC_INFO << parsedData;
}

void AmmeterScale::onSendedData(QByteArray data)
{
    QStringList sendedData;
    onParseData(sendedData, data);
    sendedData[MODBUS_WND_TXRX_RESULT_COLUMNS::STATUS] = "[TX " + sendedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::STATUS);
    qDebug() << Q_FUNC_INFO << sendedData;
}

void AmmeterScale::onRecvedData(QByteArray data)
{
    if (BasicSettingWidget::getOprtMode() == BasicSettingWidget::MASHWELDER_MODE) {
        QStringList receivedData;
        onParseData(receivedData, data);
        receivedData[MODBUS_WND_TXRX_RESULT_COLUMNS::STATUS] = "[RX " + receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::STATUS);
        m_timerAutoSend->stop();
        #ifdef NEW_AMMETER
        if ( (receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::FUNCTION) == "03") ) //parse the ammeter data NEW
        #else
        if ( (receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::FUNCTION) == "04") ) //parse the ammeter data OLD
        #endif
        {
            m_mutex.lock();
            if (m_TxQuene == TX_VOL_CMD) {
                QString voltageString = receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::RAWDATA);//:voltage
                QStringList rawlist;
                rawlist.clear();
                rawlist = voltageString.split(" ");
                if (rawlist.length()>6) {
                    QString str1 = "";
                    QString str2 = "";
                    QString rawstr = "";
                    for (int i = 0;i<rawlist.length();i++) {
                        if (i==3) {
                            str1 = rawlist.at(i);
                        }
                        if (i==4) {
                            str2 = rawlist.at(i);
                        }
                    }
                    rawstr = str1+str2;
                    int hex = rawstr.toInt(0,16);
                    int  b = 0.0;
                    if (hex%10 >= 5) {
                        b = hex / 10 + 1;
                    }
                    else {
                        b = hex / 10;
                    }
                    emit sendAmmeterVolData(b);
                }
                m_RxQuene = RX_KVA_CMD;
            }
            if (m_TxQuene == TX_KVA_CMD) {
                QString ammeterData = receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::RAWDATA);//:power
                QStringList rawlist;
                rawlist.clear();
                rawlist = ammeterData.split(" ");
                qDebug() << "====KVA:====="<<rawlist;
                if (rawlist.length()>6) {
                    QString str1 = "";
                    QString str2 = "";
                    QString str3 = "";
                    QString str4 = "";
                    QString rawstr = "";
                    for (int i = 0;i<rawlist.length();i++) {
                        if (i==3) {
                            str1 = rawlist.at(i);
                        }
                        if (i==4) {
                            str2 = rawlist.at(i);
                        }
                        if (i==5) {
                            str3 = rawlist.at(i);
                        }
                        if (i==6) {
                            str4 = rawlist.at(i);
                        }
                    }
                    rawstr = str1+str2+str3+str4;
                    int hex = rawstr.toInt(0,16);
                    //float b = *(float*)&hex;
                    float b = (float)hex;
                    float c = b / 100.00 * 30;
                    //emit sendAmmeterPowerData(b);//Power
                    emit sendAmmeterPowerData(c);
                }
                m_RxQuene = RX_VOL_CMD;
            }
            m_mutex.unlock();
        }
        qDebug() << Q_FUNC_INFO << receivedData;
        m_timerAutoSend->start();
    }
    else if (BasicSettingWidget::getOprtMode() == BasicSettingWidget::PLASTIC_MODE) {

        QStringList receivedData;
        onParseData(receivedData, data);
        receivedData[MODBUS_WND_TXRX_RESULT_COLUMNS::STATUS] = "[RX " + receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::STATUS);
        m_timerAutoSend->stop();
        if ((receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::SLAVE_ADDR) == "01") && \
           (receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::FUNCTION) == "03")) //parse the ammeter data
        {
            m_mutex.lock();
            if (m_TxQuene == TX_VOL_CMD) {
                QString voltageString = receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::RAWDATA);
                QStringList rawlist;
                rawlist.clear();
                rawlist = voltageString.split(" ");
                if (rawlist.length()>6) {
                    QString str1 = "";
                    QString str2 = "";
                    QString str3 = "";
                    QString str4 = "";
                    QString rawstr = "";
                    for (int i = 0;i<rawlist.length();i++) {
                        if (i==3) {
                            str1 = rawlist.at(i);
                        }
                        if (i==4) {
                            str2 = rawlist.at(i);
                        }
                        if (i==5) {
                            str3 = rawlist.at(i);
                        }
                        if (i==6) {
                            str4 = rawlist.at(i);
                        }
                    }
                    rawstr = str1+str2+str3+str4;
                    int hex = rawstr.toInt(0,16);
                    float b = *(float*)&hex;
                    emit sendAmmeterVolData(b);//voltage
                }
                m_RxQuene = RX_KVA_CMD;
            }
            if (m_TxQuene == TX_KVA_CMD) {
                QString ammeterData = receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::RAWDATA);
                QStringList rawlist;
                rawlist.clear();
                rawlist = ammeterData.split(" ");
                if (rawlist.length()>6) {
                    QString str1 = "";
                    QString str2 = "";
                    QString str3 = "";
                    QString str4 = "";
                    QString rawstr = "";
                    for (int i = 0;i<rawlist.length();i++) {
                        if (i==3) {
                            str1 = rawlist.at(i);
                        }
                        if (i==4) {
                            str2 = rawlist.at(i);
                        }
                        if (i==5) {
                            str3 = rawlist.at(i);
                        }
                        if (i==6) {
                            str4 = rawlist.at(i);
                        }
                    }
                    rawstr = str1+str2+str3+str4;
                    int hex = rawstr.toInt(0,16);
                    // float b = *(float*)&hex;
                    // 以下代码为10-08日修改，如果有错误或bug，以南厂运行中的代码为准。  --baixuefeng
                    float b = (float)hex;
                    float c = b / 100.00* 30;
                    emit sendAmmeterPowerData(c);//Power
                }
                m_RxQuene = RX_MODULE1_TEMPREATER;
            }
            m_mutex.unlock();
        }
        else if ((receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::SLAVE_ADDR) == "03") && \
                 (receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::FUNCTION) == "03")) //parse the temperature data
        {
            m_mutex.lock();
            if (m_TxQuene == TX_MODULE1_TEMPERATER) {
                QString ammeterData = receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::RAWDATA);
                QStringList rawlist;
                rawlist.clear();
                rawlist = ammeterData.split(" ");
                if (rawlist.length()>6) {
                    QString str1 = "";
                    QString str2 = "";
                    QString rawstr = "";
                    for (int i = 0;i<rawlist.length();i++) {
                        if (i==3) {
                            str1 = rawlist.at(i);
                        }
                        if (i==4) {
                            str2 = rawlist.at(i);
                        }
                    }
                    rawstr = str1+str2;
                    int hex = rawstr.toInt(0,16);
                    int  b = 0.0;
                    if (hex%10 >= 5) {
                        b = hex / 10 + 1;
                    }
                    else {
                        b = hex / 10;
                    }
                    emit sendTemperature(b);
                }
            }
            m_RxQuene = RX_MODULE2_TEMPREATER;
            //m_RxQuene = RX_VOL_CMD;
            m_mutex.unlock();
        }
        else if ((receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::SLAVE_ADDR) == "04") && \
                 (receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::FUNCTION) == "03")) //parse the temperature data
        {
            m_mutex.lock();
            if (m_TxQuene == TX_MODULE2_TEMPERATER) {
                QString ammeterData = receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::RAWDATA);
                QStringList rawlist;
                rawlist.clear();
                rawlist = ammeterData.split(" ");
                if (rawlist.length()>6) {
                    QString str1 = "";
                    QString str2 = "";
                    QString rawstr = "";
                    for (int i = 0;i<rawlist.length();i++) {
                        if (i==3) {
                            str1 = rawlist.at(i);
                        }
                        if (i==4) {
                            str2 = rawlist.at(i);
                        }
                    }
                    rawstr = str1+str2;
                    int hex = rawstr.toInt(0,16);
                    int  b = 0.0;
                    if (hex%10 >= 5) {
                        b = hex / 10 + 1;
                    }
                    else {
                        b = hex / 10;
                    }
                    emit sendModule2Temperature(b);
                }
            }
            m_RxQuene = RX_VOL_CMD;
            m_mutex.unlock();
        }
        qDebug() << Q_FUNC_INFO << receivedData;
        m_timerAutoSend->start();
    }
    else if (BasicSettingWidget::getOprtMode() == BasicSettingWidget::PUNCHING_MODE){
        QStringList receivedData;
        onParseData(receivedData, data);
        receivedData[MODBUS_WND_TXRX_RESULT_COLUMNS::STATUS] = "[RX " + receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::STATUS);
        m_timerAutoSend->stop();
        if ((receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::SLAVE_ADDR) == "01") && \
           (receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::FUNCTION) == "03")) //parse the ammeter data NEW
        {
            m_mutex.lock();
            if (m_TxQuene == TX_VOL_CMD) {
                QString voltageString = receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::RAWDATA);//:voltage
                QStringList rawlist;
                rawlist.clear();
                rawlist = voltageString.split(" ");
                if (rawlist.length()>6) {
                    QString str1 = "";
                    QString str2 = "";
                    QString rawstr = "";
                    for (int i = 0;i<rawlist.length();i++) {
                        if (i==3) {
                            str1 = rawlist.at(i);
                        }
                        if (i==4) {
                            str2 = rawlist.at(i);
                        }
                    }
                    rawstr = str1+str2;
                    int hex = rawstr.toInt(0,16);
                    int  b = 0.0;
                    if (hex%10 >= 5) {
                        b = hex / 10 + 1;
                    }
                    else {
                        b = hex / 10;
                    }
                    emit sendAmmeterVolData(b);
                }
                m_RxQuene = RX_KVA_CMD;
            }
            if (m_TxQuene == TX_KVA_CMD) {
                QString ammeterData = receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::RAWDATA);//:power
                QStringList rawlist;
                rawlist.clear();
                rawlist = ammeterData.split(" ");
                if (rawlist.length()>6) {
                    QString str1 = "";
                    QString str2 = "";
                    QString str3 = "";
                    QString str4 = "";
                    QString rawstr = "";
                    for (int i = 0;i<rawlist.length();i++) {
                        if (i==3) {
                            str1 = rawlist.at(i);
                        }
                        if (i==4) {
                            str2 = rawlist.at(i);
                        }
                        if (i==5) {
                            str3 = rawlist.at(i);
                        }
                        if (i==6) {
                            str4 = rawlist.at(i);
                        }
                    }
                    rawstr = str1+str2+str3+str4;
                    int hex = rawstr.toInt(0,16);
                    float b = (float)hex;
                    float c = b / 100.00 * 30;
                    emit sendAmmeterPowerData(c);
                }
                m_RxQuene = RX_VOL_CMD_1;
            }
            m_mutex.unlock();
        }

        else if ((receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::SLAVE_ADDR) == "02") && \
           (receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::FUNCTION) == "03")) //parse the ammeter data NEW
        {
            m_mutex.lock();
            if (m_TxQuene == TX_VOL_CMD_1) {
                QString voltageString = receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::RAWDATA);//:voltage
                QStringList rawlist;
                rawlist.clear();
                rawlist = voltageString.split(" ");
                if (rawlist.length()>6) {
                    QString str1 = "";
                    QString str2 = "";
                    QString rawstr = "";
                    for (int i = 0;i<rawlist.length();i++) {
                        if (i==3) {
                            str1 = rawlist.at(i);
                        }
                        if (i==4) {
                            str2 = rawlist.at(i);
                        }
                    }
                    rawstr = str1+str2;
                    int hex = rawstr.toInt(0,16);
                    int  b = 0.0;
                    if (hex%10 >= 5) {
                        b = hex / 10 + 1;
                    }
                    else {
                        b = hex / 10;
                    }
                    emit sendAmmeterVolData_1(b);
                }
                m_RxQuene = RX_KVA_CMD_1;
            }
            if (m_TxQuene == TX_KVA_CMD_1) {
                QString ammeterData = receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::RAWDATA);//:power
                QStringList rawlist;
                rawlist.clear();
                rawlist = ammeterData.split(" ");
                if (rawlist.length()>6) {
                    QString str1 = "";
                    QString str2 = "";
                    QString str3 = "";
                    QString str4 = "";
                    QString rawstr = "";
                    for (int i = 0;i<rawlist.length();i++) {
                        if (i==3) {
                            str1 = rawlist.at(i);
                        }
                        if (i==4) {
                            str2 = rawlist.at(i);
                        }
                        if (i==5) {
                            str3 = rawlist.at(i);
                        }
                        if (i==6) {
                            str4 = rawlist.at(i);
                        }
                    }
                    rawstr = str1+str2+str3+str4;
                    int hex = rawstr.toInt(0,16);
                    float b = (float)hex;
                    float c = b / 100.00 * 30;
                    emit sendAmmeterPowerData_1(c);
                }
                m_RxQuene = RX_VOL_CMD_2;
            }
            m_mutex.unlock();
        }

        else if ((receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::SLAVE_ADDR) == "03") && \
           (receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::FUNCTION) == "03")) //parse the ammeter data NEW
        {
            m_mutex.lock();
            if (m_TxQuene == TX_VOL_CMD_2) {
                QString voltageString = receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::RAWDATA);//:voltage
                QStringList rawlist;
                rawlist.clear();
                rawlist = voltageString.split(" ");
                if (rawlist.length()>6) {
                    QString str1 = "";
                    QString str2 = "";
                    QString rawstr = "";
                    for (int i = 0;i<rawlist.length();i++) {
                        if (i==3) {
                            str1 = rawlist.at(i);
                        }
                        if (i==4) {
                            str2 = rawlist.at(i);
                        }
                    }
                    rawstr = str1+str2;
                    int hex = rawstr.toInt(0,16);
                    int  b = 0.0;
                    if (hex%10 >= 5) {
                        b = hex / 10 + 1;
                    }
                    else {
                        b = hex / 10;
                    }
                    emit sendAmmeterVolData_2(b);
                }
                m_RxQuene = RX_KVA_CMD_2;
            }
            if (m_TxQuene == TX_KVA_CMD_2) {
                QString ammeterData = receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::RAWDATA);//:power
                QStringList rawlist;
                rawlist.clear();
                rawlist = ammeterData.split(" ");
                if (rawlist.length()>6) {
                    QString str1 = "";
                    QString str2 = "";
                    QString str3 = "";
                    QString str4 = "";
                    QString rawstr = "";
                    for (int i = 0;i<rawlist.length();i++) {
                        if (i==3) {
                            str1 = rawlist.at(i);
                        }
                        if (i==4) {
                            str2 = rawlist.at(i);
                        }
                        if (i==5) {
                            str3 = rawlist.at(i);
                        }
                        if (i==6) {
                            str4 = rawlist.at(i);
                        }
                    }
                    rawstr = str1+str2+str3+str4;
                    int hex = rawstr.toInt(0,16);
                    float b = (float)hex;
                    float c = b / 100.00 * 30;
                    emit sendAmmeterPowerData_2(c);
                }
                m_RxQuene = RX_VOL_CMD_3;
            }
            m_mutex.unlock();
        }

        else if ((receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::SLAVE_ADDR) == "04") && \
           (receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::FUNCTION) == "03")) //parse the ammeter data NEW
        {
            m_mutex.lock();
            if (m_TxQuene == TX_VOL_CMD_3) {
                QString voltageString = receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::RAWDATA);//:voltage
                QStringList rawlist;
                rawlist.clear();
                rawlist = voltageString.split(" ");
                if (rawlist.length()>6) {
                    QString str1 = "";
                    QString str2 = "";
                    QString rawstr = "";
                    for (int i = 0;i<rawlist.length();i++) {
                        if (i==3) {
                            str1 = rawlist.at(i);
                        }
                        if (i==4) {
                            str2 = rawlist.at(i);
                        }
                    }
                    rawstr = str1+str2;
                    int hex = rawstr.toInt(0,16);
                    int  b = 0.0;
                    if (hex%10 >= 5) {
                        b = hex / 10 + 1;
                    }
                    else {
                        b = hex / 10;
                    }
                    emit sendAmmeterVolData_3(b);
                }
                m_RxQuene = RX_KVA_CMD_3;
            }
            if (m_TxQuene == TX_KVA_CMD_3) {
                QString ammeterData = receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::RAWDATA);//:power
                QStringList rawlist;
                rawlist.clear();
                rawlist = ammeterData.split(" ");
                if (rawlist.length()>6) {
                    QString str1 = "";
                    QString str2 = "";
                    QString str3 = "";
                    QString str4 = "";
                    QString rawstr = "";
                    for (int i = 0;i<rawlist.length();i++) {
                        if (i==3) {
                            str1 = rawlist.at(i);
                        }
                        if (i==4) {
                            str2 = rawlist.at(i);
                        }
                        if (i==5) {
                            str3 = rawlist.at(i);
                        }
                        if (i==6) {
                            str4 = rawlist.at(i);
                        }
                    }
                    rawstr = str1+str2+str3+str4;
                    int hex = rawstr.toInt(0,16);
                    float b = (float)hex;
                    float c = b / 100.00 * 30;
                    emit sendAmmeterPowerData_3(c);
                }
                m_RxQuene = RX_MODULE1_TEMPREATER;
            }
            m_mutex.unlock();
        }

        else if ((receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::SLAVE_ADDR) == "05") && \
                 (receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::FUNCTION) == "03")) //parse the temperature data
        {
            m_mutex.lock();
            if (m_TxQuene == TX_MODULE1_TEMPERATER) {
                QString ammeterData = receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::RAWDATA);
                QStringList rawlist;
                int hex;
                rawlist.clear();
                rawlist = ammeterData.split(" ");
                if (rawlist.length()>6) {
                    QString str1 = "";
                    QString str2 = "";
                    QString str3 = "";
                    QString str4 = "";
                    QString str5 = "";
                    QString str6 = "";
                    QString rawstr = "";
                    for (int i = 0;i<rawlist.length();i++) {
                        if (i==3) {
                            str1 = rawlist.at(i);
                        }
                        if (i==4) {
                            str2 = rawlist.at(i);
                        }
                        if (i==5) {
                            str3 = rawlist.at(i);
                        }
                        if (i==6) {
                            str4 = rawlist.at(i);
                        }
                        if (i==7) {
                            str5 = rawlist.at(i);
                        }
                        if (i==8) {
                            str6 = rawlist.at(i);
                        }
                    }
                    /*Temperature 1*/
                    rawstr = str1+str2;
                    hex = rawstr.toInt(0,16);
                    int  Temper1 = 0.0;

                    Temper1 = (hex / 10);

                    emit sendTemperature(Temper1);

                    /*Temperature 2*/
                    rawstr = str3+str4;
                    hex = rawstr.toInt(0,16);
                    int  Temper2 = 0.0;

                    Temper2 = hex / 10;
                    if(Temper2 > 2000)
                    {
                        Temper2 = 0;
                        emit sendTemperature_1(Temper2);
                    }
                    else
                    {
                        emit sendTemperature_1(Temper2);
                    }

                    /*Temperature 3*/
                    rawstr = str5+str6;
                    hex = rawstr.toInt(0,16);
                    int  Temper3 = 0.0;

                    Temper3 = hex / 10;
                    if(Temper3 > 2000)
                    {
                        Temper3 = 0;
                        emit sendTemperature_2(Temper3);
                    }
                    else
                    {
                        emit sendTemperature_2(Temper3);
                    }
                }
            }
            //m_RxQuene = RX_MODULE2_TEMPREATER;
            m_RxQuene = RX_VOL_CMD;
            m_mutex.unlock();
        }
        qDebug() << Q_FUNC_INFO << receivedData;
        m_timerAutoSend->start();
    }
}


void AmmeterScale::onRecvedErrorData(QByteArray data)
{
    QStringList receivedData;
    onParseData(receivedData, data);
    receivedData[MODBUS_WND_TXRX_RESULT_COLUMNS::STATUS] = "[RX " + receivedData.at(MODBUS_WND_TXRX_RESULT_COLUMNS::STATUS);
}

quint32 AmmeterScale::onCmbBaudrateTextChanged(QString str)
{
    QMetaObject::invokeMethod(m_port, "changeBaudrate", Qt::BlockingQueuedConnection,
                              Q_ARG(quint32, str.toInt()  ));

    return str.toInt();
}

quint32 AmmeterScale::onCmbDataBitsTextChanged(QString str)
{
    QMetaObject::invokeMethod(m_port, "changeDataBits", Qt::BlockingQueuedConnection,
                              Q_ARG(quint32, str.toInt()  ));

    return str.toInt();
}
quint32 AmmeterScale::onCmbParityTextChanged(QString str)
{
    QSerialPort::Parity parity = QSerialPort::UnknownParity;

    if( str == "none" )
    {
        parity = QSerialPort::NoParity;
    }
    else if ( str == "even" )
    {
        parity = QSerialPort::EvenParity;
    }
    else if ( str == "odd" )
    {
        parity = QSerialPort::OddParity;
    }

    QMetaObject::invokeMethod(m_port, "changeParity", Qt::BlockingQueuedConnection,
                              Q_ARG(quint32, parity  ));

    return parity;
}
quint32 AmmeterScale::onCmbStopBitsTextChanged(QString str)
{
    QSerialPort::StopBits stopBits = QSerialPort::UnknownStopBits;
    if( str.toInt() == 1 )
        stopBits = QSerialPort::OneStop;
    else if ( str.toInt() == 2)
        stopBits = QSerialPort::TwoStop;

    QMetaObject::invokeMethod(m_port, "changeStopBits", Qt::BlockingQueuedConnection,
                              Q_ARG(quint32, stopBits  ));

    return stopBits;
}

void AmmeterScale::onPortConnected()
{
    emit sgConnected("Connected");
}

void AmmeterScale::onPortDisconnected()
{
    m_timerAutoSend->stop();
    emit sgDisconnected( m_port->errorString());
    onTryConnectPort();
}

void AmmeterScale::onReceiveWriteList(QStringList parsedData)
{
    QByteArray sendData;
    QString rawData = "";
    for (int i = 0; i < parsedData.count(); i++) {
        if (i==3) {
            rawData = parsedData.at(3);
        }
    }
    sendData = QByteArray::fromHex( rawData.toLatin1() );
    qDebug() << Q_FUNC_INFO << sendData.toHex();
    QMetaObject::invokeMethod(m_port, "sendData", Qt::BlockingQueuedConnection,
                              Q_ARG(QByteArray, sendData ));
}

void AmmeterScale::onTimerAutoSendTimeout()
{
    qDebug () << Q_FUNC_INFO;
    onReadyEntered();
}

void AmmeterScale::onReadyEntered()
{
    if (BasicSettingWidget::getOprtMode() == BasicSettingWidget::MASHWELDER_MODE) {

        if (m_RxQuene == RX_VOL_CMD) {
            m_mutex.lock();
            QByteArray sendData;

            #ifdef NEW_AMMETER
            QString arr = "01 03 00 61 00 01 D5 D4"; //request Vol new
            //QString arr = "01 03 00 42 00 02 64 1F";
            #else
            QString arr = "02 04 00 00 00 02 71 F8"; //request Vol old
            #endif
            sendData = QByteArray::fromHex( arr.toLatin1());
            QMetaObject::invokeMethod(m_port, "sendData", Qt::BlockingQueuedConnection,
                                      Q_ARG(QByteArray, sendData ));
            m_TxQuene = TX_VOL_CMD;
            m_mutex.unlock();
        }

        if (m_RxQuene == RX_KVA_CMD) {
            m_mutex.lock();
            QByteArray sendData;
            #ifdef NEW_AMMETER
//            //QString arr = "01 03 01 6A 00 02 E5 EB";//request power new
//            //QString arr = "01 03 00 00 00 02 C4 0B";
            QString arr = "01 03 00 00 00 04 44 09";
            #else
            QString arr = "02 04 01 00 00 02 70 04";//request power old
            #endif
            sendData = QByteArray::fromHex( arr.toLatin1());
            QMetaObject::invokeMethod(m_port, "sendData", Qt::BlockingQueuedConnection,
                                      Q_ARG(QByteArray, sendData ));
            m_TxQuene = TX_KVA_CMD;
            m_mutex.unlock();
        }
        m_timerAutoSend->stop();

    }
    else if (BasicSettingWidget::getOprtMode() == BasicSettingWidget::PLASTIC_MODE) {
        switch(m_RxQuene)
        {
            case RX_VOL_CMD:
            {
                m_mutex.lock();
                QByteArray sendData;
                QString arr = "01 03 00 78 00 01 04 13"; //request Vol
                sendData = QByteArray::fromHex( arr.toLatin1());
                QMetaObject::invokeMethod(m_port, "sendData", Qt::BlockingQueuedConnection,
                                          Q_ARG(QByteArray, sendData ));
                m_TxQuene = TX_VOL_CMD;
                m_RxQuene = RX_KVA_CMD;
                m_mutex.unlock();
            break;
            }

            case RX_KVA_CMD:
            {
                m_mutex.lock();
                QByteArray sendData;
                QString arr = "01 03 00 00 00 02 C4 0B";
                sendData = QByteArray::fromHex( arr.toLatin1());
                QMetaObject::invokeMethod(m_port, "sendData", Qt::BlockingQueuedConnection,
                                          Q_ARG(QByteArray, sendData ));
                m_TxQuene = TX_KVA_CMD;
                m_RxQuene = RX_MODULE1_TEMPREATER;
                m_mutex.unlock();
            break;
            }

            case RX_MODULE1_TEMPREATER:
            {
                m_mutex.lock();
                readAmmeterInfo("03","03","1001","01","RTU",""); //request module1 temperature
                m_mutex.unlock();
                m_TxQuene = TX_MODULE1_TEMPERATER;
                m_RxQuene = RX_MODULE2_TEMPREATER;
            break;
            }

            case RX_MODULE2_TEMPREATER:
            {
                m_mutex.lock();
                readAmmeterInfo("04","03","1001","01","RTU",""); //request module1 temperature
                m_mutex.unlock();
                m_TxQuene = TX_MODULE2_TEMPERATER;
                m_RxQuene = RX_VOL_CMD;
            break;
            }
            default:
            {
                m_mutex.lock();
                QByteArray sendData;
                QString arr = "01 03 00 00 00 02 C4 0B";
                sendData = QByteArray::fromHex( arr.toLatin1());
                QMetaObject::invokeMethod(m_port, "sendData", Qt::BlockingQueuedConnection,
                                          Q_ARG(QByteArray, sendData ));
                m_TxQuene = TX_KVA_CMD;
                m_RxQuene = RX_MODULE1_TEMPREATER;
                m_mutex.unlock();
                break;
            }
        }
        m_timerAutoSend->stop();
    }
    else if (BasicSettingWidget::getOprtMode() == BasicSettingWidget::PUNCHING_MODE) {
        switch(m_RxQuene)
        {
            case RX_VOL_CMD:
            {
                m_mutex.lock();
                QByteArray sendData;
                QString arr = "01 03 00 78 00 01 04 13"; //request Vol
                sendData = QByteArray::fromHex( arr.toLatin1());
                QMetaObject::invokeMethod(m_port, "sendData", Qt::BlockingQueuedConnection,
                                          Q_ARG(QByteArray, sendData ));
                m_TxQuene = TX_VOL_CMD;
                m_RxQuene = RX_KVA_CMD;
                m_mutex.unlock();
            break;
            }

            case RX_KVA_CMD:
            {
                m_mutex.lock();
                QByteArray sendData;
                QString arr = "01 03 00 00 00 02 C4 0B";
                sendData = QByteArray::fromHex( arr.toLatin1());
                QMetaObject::invokeMethod(m_port, "sendData", Qt::BlockingQueuedConnection,
                                          Q_ARG(QByteArray, sendData ));
                m_TxQuene = TX_KVA_CMD;
                m_RxQuene = RX_VOL_CMD_1;
                m_mutex.unlock();
            break;
            }

            case RX_VOL_CMD_1:
            {
                m_mutex.lock();
                QByteArray sendData;
                QString arr = "02 03 00 78 00 01 04 20"; //request Vol
                sendData = QByteArray::fromHex( arr.toLatin1());
                QMetaObject::invokeMethod(m_port, "sendData", Qt::BlockingQueuedConnection,
                                          Q_ARG(QByteArray, sendData ));
                m_TxQuene = TX_VOL_CMD_1;
                m_RxQuene = RX_KVA_CMD_1;
                m_mutex.unlock();
            break;
            }

            case RX_KVA_CMD_1:
            {
                m_mutex.lock();
                QByteArray sendData;
                QString arr = "02 03 00 00 00 02 C4 38";
                sendData = QByteArray::fromHex( arr.toLatin1());
                QMetaObject::invokeMethod(m_port, "sendData", Qt::BlockingQueuedConnection,
                                          Q_ARG(QByteArray, sendData ));
                m_TxQuene = TX_KVA_CMD_1;
                m_RxQuene = RX_VOL_CMD_2;
                m_mutex.unlock();
            break;
            }

            case RX_VOL_CMD_2:
            {
                m_mutex.lock();
                QByteArray sendData;
                QString arr = "03 03 00 78 00 01 05 F1"; //request Vol
                sendData = QByteArray::fromHex( arr.toLatin1());
                QMetaObject::invokeMethod(m_port, "sendData", Qt::BlockingQueuedConnection,
                                          Q_ARG(QByteArray, sendData ));
                m_TxQuene = TX_VOL_CMD_2;
                m_RxQuene = RX_KVA_CMD_2;
                m_mutex.unlock();
            break;
            }

            case RX_KVA_CMD_2:
            {
                m_mutex.lock();
                QByteArray sendData;
                QString arr = "03 03 00 00 00 02 C5 E9";
                sendData = QByteArray::fromHex( arr.toLatin1());
                QMetaObject::invokeMethod(m_port, "sendData", Qt::BlockingQueuedConnection,
                                          Q_ARG(QByteArray, sendData ));
                m_TxQuene = TX_KVA_CMD_2;
                m_RxQuene = RX_VOL_CMD_3;
                m_mutex.unlock();
            break;
            }

            case RX_VOL_CMD_3:
            {
                m_mutex.lock();
                QByteArray sendData;
                QString arr = "04 03 00 78 00 01 04 46"; //request Vol
                sendData = QByteArray::fromHex( arr.toLatin1());
                QMetaObject::invokeMethod(m_port, "sendData", Qt::BlockingQueuedConnection,
                                          Q_ARG(QByteArray, sendData ));
                m_TxQuene = TX_VOL_CMD_3;
                m_RxQuene = RX_KVA_CMD_3;
                m_mutex.unlock();
            break;
            }

            case RX_KVA_CMD_3:
            {
                m_mutex.lock();
                QByteArray sendData;
                QString arr = "04 03 00 00 00 02 C4 5E";
                sendData = QByteArray::fromHex( arr.toLatin1());
                QMetaObject::invokeMethod(m_port, "sendData", Qt::BlockingQueuedConnection,
                                          Q_ARG(QByteArray, sendData ));
                m_TxQuene = TX_KVA_CMD_3;
                m_RxQuene = RX_MODULE1_TEMPREATER;
                m_mutex.unlock();
            break;
            }

            case RX_MODULE1_TEMPREATER:
            {
                m_mutex.lock();
                readAmmeterInfo("05","03","0002","03","RTU",""); //request module1 temperature
                m_mutex.unlock();
                m_TxQuene = TX_MODULE1_TEMPERATER;
                m_RxQuene = RX_VOL_CMD;
            break;
            }

            default:
            {
                m_mutex.lock();
                QByteArray sendData;
                QString arr = "01 03 00 00 00 02 C4 0B";
                sendData = QByteArray::fromHex( arr.toLatin1());
                QMetaObject::invokeMethod(m_port, "sendData", Qt::BlockingQueuedConnection,
                                              Q_ARG(QByteArray, sendData ));
                 m_TxQuene = TX_KVA_CMD;
                 m_RxQuene = RX_VOL_CMD;
                 m_mutex.unlock();
                 break;
            }
        }
        m_timerAutoSend->stop();
    }


}

void AmmeterScale::onTryConnectPort()
{
    QMetaObject::invokeMethod(m_port, "tryConnect", Qt::QueuedConnection ,
                              Q_ARG(QString, mComPortSetting.cmbComPort),
                              Q_ARG(quint32, onCmbBaudrateTextChanged(mComPortSetting.cmbBaudrate) ),
                              Q_ARG(quint32, onCmbDataBitsTextChanged(mComPortSetting.cmbDataBits) ),
                              Q_ARG(quint32, onCmbParityTextChanged(mComPortSetting.cmbParity) ),
                              Q_ARG(quint32, onCmbStopBitsTextChanged(mComPortSetting.cmbStopBits) )
                              );
}


bool AmmeterScale::check_ModbusRTU_CRC16(QByteArray buf, quint16 &result)
{
    if( buf.size() >= 4 )
    {
        QByteArray srcCrc = buf.mid(buf.size()-2, 2);
        QByteArray dstCrc = "";
        quint16 crc = AmmeterScale::ModbusRTU_CRC16(buf.constData(), buf.size() -2 );
        dstCrc = QByteArray::fromRawData((char*)&crc, 2);
        result = crc;
        if( srcCrc == dstCrc )
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    result = 0xffff;
    return false;
}

quint16 AmmeterScale::ModbusRTU_CRC16 (const char *buf, quint16 wLength)
{
    static const quint16 wCRCTable[] = {
        0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241,
        0XC601, 0X06C0, 0X0780, 0XC741, 0X0500, 0XC5C1, 0XC481, 0X0440,
        0XCC01, 0X0CC0, 0X0D80, 0XCD41, 0X0F00, 0XCFC1, 0XCE81, 0X0E40,
        0X0A00, 0XCAC1, 0XCB81, 0X0B40, 0XC901, 0X09C0, 0X0880, 0XC841,
        0XD801, 0X18C0, 0X1980, 0XD941, 0X1B00, 0XDBC1, 0XDA81, 0X1A40,
        0X1E00, 0XDEC1, 0XDF81, 0X1F40, 0XDD01, 0X1DC0, 0X1C80, 0XDC41,
        0X1400, 0XD4C1, 0XD581, 0X1540, 0XD701, 0X17C0, 0X1680, 0XD641,
        0XD201, 0X12C0, 0X1380, 0XD341, 0X1100, 0XD1C1, 0XD081, 0X1040,
        0XF001, 0X30C0, 0X3180, 0XF141, 0X3300, 0XF3C1, 0XF281, 0X3240,
        0X3600, 0XF6C1, 0XF781, 0X3740, 0XF501, 0X35C0, 0X3480, 0XF441,
        0X3C00, 0XFCC1, 0XFD81, 0X3D40, 0XFF01, 0X3FC0, 0X3E80, 0XFE41,
        0XFA01, 0X3AC0, 0X3B80, 0XFB41, 0X3900, 0XF9C1, 0XF881, 0X3840,
        0X2800, 0XE8C1, 0XE981, 0X2940, 0XEB01, 0X2BC0, 0X2A80, 0XEA41,
        0XEE01, 0X2EC0, 0X2F80, 0XEF41, 0X2D00, 0XEDC1, 0XEC81, 0X2C40,
        0XE401, 0X24C0, 0X2580, 0XE541, 0X2700, 0XE7C1, 0XE681, 0X2640,
        0X2200, 0XE2C1, 0XE381, 0X2340, 0XE101, 0X21C0, 0X2080, 0XE041,
        0XA001, 0X60C0, 0X6180, 0XA141, 0X6300, 0XA3C1, 0XA281, 0X6240,
        0X6600, 0XA6C1, 0XA781, 0X6740, 0XA501, 0X65C0, 0X6480, 0XA441,
        0X6C00, 0XACC1, 0XAD81, 0X6D40, 0XAF01, 0X6FC0, 0X6E80, 0XAE41,
        0XAA01, 0X6AC0, 0X6B80, 0XAB41, 0X6900, 0XA9C1, 0XA881, 0X6840,
        0X7800, 0XB8C1, 0XB981, 0X7940, 0XBB01, 0X7BC0, 0X7A80, 0XBA41,
        0XBE01, 0X7EC0, 0X7F80, 0XBF41, 0X7D00, 0XBDC1, 0XBC81, 0X7C40,
        0XB401, 0X74C0, 0X7580, 0XB541, 0X7700, 0XB7C1, 0XB681, 0X7640,
        0X7200, 0XB2C1, 0XB381, 0X7340, 0XB101, 0X71C0, 0X7080, 0XB041,
        0X5000, 0X90C1, 0X9181, 0X5140, 0X9301, 0X53C0, 0X5280, 0X9241,
        0X9601, 0X56C0, 0X5780, 0X9741, 0X5500, 0X95C1, 0X9481, 0X5440,
        0X9C01, 0X5CC0, 0X5D80, 0X9D41, 0X5F00, 0X9FC1, 0X9E81, 0X5E40,
        0X5A00, 0X9AC1, 0X9B81, 0X5B40, 0X9901, 0X59C0, 0X5880, 0X9841,
        0X8801, 0X48C0, 0X4980, 0X8941, 0X4B00, 0X8BC1, 0X8A81, 0X4A40,
        0X4E00, 0X8EC1, 0X8F81, 0X4F40, 0X8D01, 0X4DC0, 0X4C80, 0X8C41,
        0X4400, 0X84C1, 0X8581, 0X4540, 0X8701, 0X47C0, 0X4680, 0X8641,
        0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040 };

    quint8 nTemp;
    quint16 CRC16 = 0xFFFF;

    while (wLength--)
    {
        nTemp = *buf++ ^ CRC16;
        CRC16 >>= 8;
        CRC16  ^= wCRCTable[nTemp];
    }
    return CRC16;
} // End: CRC16

QByteArray AmmeterScale::makeRTUFrame(QByteArray slaveAddr, QByteArray functionCode, QByteArray startAddr,
                                      QByteArray numOfRegister, QByteArray byteCount, const QByteArray writeData)
{
    Q_ASSERT(writeData.size() <= 252);
    QByteArray modbusPDU = "";



    switch( QByteArray::fromHex(functionCode).at(0) )
    {
    case 0x02:
        modbusPDU += functionCode + startAddr + numOfRegister;//增加读报警信息
        break;
    case 0x03:
        modbusPDU += functionCode + startAddr + numOfRegister;
        break;
    case 0x04:
        modbusPDU += functionCode + startAddr + numOfRegister;
        break;
    case 0x05:
        modbusPDU += functionCode + startAddr + writeData;
        break;
    case 0x06:
        modbusPDU += functionCode + startAddr + writeData;
        break;
    case 0x10:
    case 0x0F:
        modbusPDU += functionCode + startAddr + numOfRegister + byteCount + writeData;
        break;
    default:
        modbusPDU += functionCode + startAddr + writeData;
        break;
    }
    QByteArray frame ="";
    QDataStream ds(&frame, QIODevice::WriteOnly);
    ds.setByteOrder(QDataStream::LittleEndian);
    ds << quint8(QByteArray::fromHex(slaveAddr).at(0));
    ds.writeRawData(QByteArray::fromHex(modbusPDU).constData(), modbusPDU.size() /2 );
    quint16 crc = ModbusRTU_CRC16(frame.constData(), frame.size());
    ds << quint16(crc);
    return frame;
}

QByteArray AmmeterScale::makeLSBUSFrame(QByteArray slaveAddr, QByteArray functionCode, QByteArray startAddr,
                                        QByteArray numOfRegister, QByteArray byteCount, const QByteArray writeData)
{
    Q_ASSERT(writeData.size() <= 252);
    QByteArray modbusPDU = "";

    Q_UNUSED(byteCount);
    switch( QByteArray::fromHex(functionCode).at(0) )
    {
    case 0x52:
        modbusPDU += slaveAddr + QByteArray::fromHex(functionCode).at(0) + startAddr + numOfRegister.right(1);
        break;
    case 0x57:
        modbusPDU += slaveAddr + QByteArray::fromHex(functionCode).at(0) + startAddr + numOfRegister.right(1) + writeData;
        break;
    case 0x58:
        break;
    case 0x59:
        break;
    default:
        break;
    }
    QByteArray frame ="";
    QDataStream ds(&frame, QIODevice::WriteOnly);
    ds.setByteOrder(QDataStream::LittleEndian);
    ds << quint8(0x05);
    ds.writeRawData(modbusPDU.constData(), modbusPDU.size());
    quint8 sum = LSBUS_sum(frame);
    ds.writeRawData( QByteArray::number(sum, 16).toUpper().constData(), 2 );
    ds << quint8(0x04);
    return frame;
}
